import {env} from "@/utils";
import store from "@/store";

type EventSourceCallback = (data: any) => void;
type ErrorCallback = (error: Event) => void;

interface EventSourceParams {
    [key: string]: string | number | boolean; // 限制参数值的类型
}

const {API_URL, TOKEN_NAME} = env;

if (typeof(EventSource) === "undefined") {
    console.error("您的浏览器不支持Server-Sent Events.");
}

const beforeUnloadHandler = (e: BeforeUnloadEvent) => {
    const message = "文件正在下载中，刷新或离开页面可能会中断下载。";
    e.preventDefault();
    e.returnValue = message ; // 兼容旧版浏览器
    return message; // 现代浏览器
}

export class ProgressEventSourceWrapper {
    private readonly baseUrl: string; // 基础 URL
    private readonly options: EventSourceParams; // 全局配置
    private eventSource: EventSource | null = null; // EventSource 实例
    private onMessageCallback: EventSourceCallback | null = null; // 消息回调
    private onStartCallback: (() => void) | null = null; // 开始回调
    private onCloseCallback: (() => void) | null = null; // 结束回调
    private onErrorCallback: ErrorCallback | null = null; // 错误回调

    constructor(baseUrl: string, options: EventSourceParams = {}) {
        this.baseUrl = `${API_URL}${baseUrl}`;
        this.options = options;
        this.options[TOKEN_NAME] = store.userStore.token;
    }

    // 初始化或重新连接，支持链式调用
    onOpen(params: EventSourceParams = {}): this {
        // 关闭现有连接
        if (this.eventSource) {
            this.close();
        }

        // 构建带参数的 URL
        let url: URL;
        try {
            url = new URL(this.baseUrl);
        } catch (error) {
            url = new URL(this.baseUrl, window.location.origin);
        }
        Object.entries(Object.assign(params, this.options)).forEach(([key, value]) => {
            if (value !== undefined && value !== null) {
                url.searchParams.append(key, String(value)); // 确保参数值为字符串
            }
        });

        // 初始化 EventSource
        this.eventSource = new EventSource(url.toString());

        // 绑定事件处理器
        this.eventSource.onmessage = (event: MessageEvent) => {
            if (this.onMessageCallback) {
                switch (event.data) {
                    case 'startup':
                        window.addEventListener('beforeunload', beforeUnloadHandler);
                        this.onStartCallback?.();
                        break;
                    case 'continue':
                        window.addEventListener('beforeunload', beforeUnloadHandler);
                        break;
                    case 'shutdown':
                        this.close();
                        this.onCloseCallback?.();
                        break;
                    default:
                        this.onMessageCallback(event.data);
                }
            }
        };

        this.eventSource.onerror = (error: Event) => {
            this.close();
            if (this.onErrorCallback) {
                this.onErrorCallback(error);
            }
        };

        // 返回 this，支持链式调用
        return this;
    }

    // 设置开始回调，支持链式调用
    onStart(callback: () => void): this {
        this.onStartCallback = callback;
        return this;
    }

    // 设置消息回调，支持链式调用
    onMessage(callback: EventSourceCallback): this {
        this.onMessageCallback = callback;
        return this;
    }

    // 设置关闭回调，支持链式调用
    onClose(callback: () => void): this {
        this.onCloseCallback = callback;
        return this;
    }

    // 设置错误回调，支持链式调用
    onError(callback: ErrorCallback): this {
        this.onErrorCallback = callback;
        return this;
    }

    // 关闭连接
    private close(): void {
        if (this.eventSource) {
            this.eventSource.close();
            this.eventSource = null;
        }
        window.removeEventListener('beforeunload', beforeUnloadHandler);
    }
}